package service

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"qld2devservice/cons"
	"qld2devservice/models"
	"qld2devservice/utils"
	"strings"
	"time"
)

const (
	UserControlErr = iota
)

var (
	msgCh  chan string
	errMsg = []string{
		"充电桩用户控制失败",
	}
)

type WxGetAccessToken struct {
	Access_token string
	Expires_in   string
}

type WxGetJsonErr struct {
	Errcode int64
	Errmsg  string
}

type WxOpenidList struct {
	Openid []string
}

type WxTagsList struct {
	Count       int64
	Data        WxOpenidList
	Next_openid string
}

func ErrorMsgInit() {
	getOpenId()
	msgCh = make(chan string, 1)
	go func() {
		for {
			err := sendErrorMsg(<-msgCh)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			}
			time.Sleep(time.Second)
		}
	}()
}

func PutErrorMsg(msg, snNum string, errType int64) {
	if cons.GRPC_TEST_MODE == cons.ENUM_SERVER {
		msg = "qld2-production " + msg
	} else if cons.GRPC_TEST_MODE == cons.ENUM_SERVER_TEST {
		msg = "qld2-test " + msg
	}
	if len(msgCh) == 0 {
		msgCh <- msg
	}
	if errType >= int64(len(errMsg)) {
		errType = 0
	}
	go models.InsertQldExceptionRecord(models.QldExceptionRecord{
		Id:         0,
		Type:       200 + errType,
		Title:      errMsg[errType],
		UserMobile: "",
		DeviceSn:   snNum,
		OrderSn:    "",
		Msg:        msg,
		CreateTime: time.Now(),
	})
}

func getOpenId() error {
	tokenBody, err := GetAccesstokenFromWx()
	if err != nil {
		//utils.MyPrint(utils.PRINT_ERROR , err.Error())
		return err
	} else {
		var requestOpenIDJSON map[string]string
		if json.Unmarshal(tokenBody, &requestOpenIDJSON); requestOpenIDJSON["access_token"] == "" {
			utils.MyPrint(utils.PRINT_WARN, "access_token获取失败")
		} else {
			tags, err := GetOpenIDFromTags(100, requestOpenIDJSON["access_token"])
			if err != nil {
				return err
			}
			//openId := []string{"oFQMj05PkglqCSxK7OFLaEqyU-DQ"}
			if err2 := RedisSaveNoHeader("/qld2devservice/wxMsgOpenId", strings.Join(tags, ",")); err2 != nil {
				err = utils.WrapError(err2, "AnalyzePower:保存充电仓电量失败")
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
				return err
			}
		}
	}
	return nil
}
func sendErrorMsg(msg string) error {
	tokenBody, err := GetAccesstokenFromWx()
	if err != nil {
		return err
	} else {
		var requestOpenIDJSON map[string]string
		if json.Unmarshal(tokenBody, &requestOpenIDJSON); requestOpenIDJSON["access_token"] == "" {
			utils.MyPrint(utils.PRINT_WARN, "access_token获取失败")
		} else {
			if wxMsgOpenId, err := RedisGetNoHeader("/qld2devservice/wxMsgOpenId", ""); err != nil {
				errNew := utils.WrapError(err, "sendErrorMsg:etcd服务电费数据获取失败")
				return errNew
			} else {
				tags := strings.Split(wxMsgOpenId, ",")
				PostMsgByWxPubilcnum(tags, msg, requestOpenIDJSON["access_token"])
			}
		}
	}
	return nil
}

func GetAccesstokenFromWx() ([]byte, error) {
	url := "https://api.weixin.qq.com/cgi-bin/token"
	grant_type := "client_credential"
	appid := "wxd33ed305343f80ae"
	secret := "77b145d3834111e2d794d088287edb03"

	url += "?grant_type=" + grant_type + "&appid=" + appid + "&secret=" + secret
	resp, err := Get(url)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "微信群发开发者获取token时错误1", err.Error())
		return nil, err
	}
	var paramStruct WxGetJsonErr
	err = json.Unmarshal(resp, &paramStruct)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "微信群发开发者获取token时错误2", err.Error())
		return nil, err
	}
	return resp, nil
}

func GetOpenIDFromTags(tagsid int64, Access_token string) ([]string, error) {
	url := "https://api.weixin.qq.com/cgi-bin/user/tag/get"
	url += "?access_token=" + Access_token
	//url += "&tagid=" + strconv.FormatInt(tagsid,10)
	//url += "&next_openid="
	//next_openid 第一个拉取的OPENID，不填默认从头开始拉取
	//requestParam := "{   \"tagid\" : "+strconv.FormatInt(tagsid,10)+",   \"next_openid\":\"\" } "
	data := map[string]interface{}{
		"tagid":       tagsid,
		"next_openid": "",
	}
	//resp,err := Get(url,requestParam)
	resp, err := Post(url, data, "application/json")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "微信群发开发者获取tag时错误1", err.Error())
		return nil, err
	}
	var paramErr WxGetJsonErr
	err = json.Unmarshal([]byte(resp), &paramErr)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "微信群发开发者获取tag时错误2", err.Error())
		return nil, err
	}
	if paramErr.Errcode != 0 {
		utils.MyPrint(utils.PRINT_ERROR, "微信群发开发者获取tag时错误3--code不为0", paramErr)
		return nil, utils.NewError(utils.ErrorTypeStop, "微信群发开发者获取tag时errcode不为0")
	}
	var param WxTagsList
	err = json.Unmarshal([]byte(resp), &param)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "微信群发开发者获取tag时错误4", err.Error())
		return nil, err
	}
	return param.Data.Openid, nil

}

func PostMsgByWxPubilcnum(openid []string, Msg, Access_token string) {
	url := "https://api.weixin.qq.com/cgi-bin/message/custom/send"
	url += "?access_token=" + Access_token

	num := len(openid)
	for i := 0; i < num; i++ {
		text := map[string]interface{}{
			"content": Msg,
		}
		data := map[string]interface{}{
			"touser":  openid[i],
			"msgtype": "text",
			"text":    text,
		}
		resp, err := Post(url, data, "application/json")
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, err.Error())
		}
		utils.MyPrint(utils.PRINT_INFO, resp)
	}
}

// 发送POST请求
// url：         请求地址
// data：        POST请求提交的数据
// contentType： 请求体格式，如：application/json
// content：     请求放回的内容
func Post(url string, data interface{}, contentType string) (string, error) {

	// 超时时间：5秒
	client := &http.Client{Timeout: 5 * time.Second}
	jsonStr, _ := json.Marshal(data)
	resp, err := client.Post(url, contentType, bytes.NewBuffer(jsonStr))
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "post111111111111111", err.Error())
		return "", err
	}
	defer resp.Body.Close()
	result, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "post111111111111111", err.Error())
		return "", err
	}
	return string(result), nil
}

// 发送GET请求
// url：         请求地址
// response：    请求返回的内容
func Get(url string) ([]byte, error) {

	// 超时时间：5秒
	client := &http.Client{Timeout: 5 * time.Second}
	//req := bytes.NewBuffer([]byte(jsonStr))
	//if jsonStr == "" {
	//	req = nil
	//}
	//request, _ := http.NewRequest("GET",url,req)
	//request.Header.Set("Connection", "keep-alive")
	//resp, err := client.Do(request)
	resp, err := client.Get(url)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "get111111111111111", err.Error())
		return nil, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "get2222222222222222", err.Error())
		return nil, err
	}
	return body, nil

}
